package com.how.config;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.how.config.base.DataSourceBase;
import org.apache.shardingsphere.api.config.masterslave.LoadBalanceStrategyConfiguration;
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.NoneShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.*;

@Configuration
public class BaseDataSourceConfig extends DataSourceBase {

    @Lazy
    @Resource
    ShardingDataSource shardingDataSource;

    @Bean(BASEDATABASE)
    public DataSource getBaseDatasource() throws Exception {
        Map<String, DataSource> dataSourceMap = shardingDataSource.getDataSourceMap();
        Set<String> keySet = dataSourceMap.keySet();
        HashMap<String, DataSource> map = Maps.newHashMap();
        List<String> slaveDataSourceNames = Lists.newArrayList();
        for (String s : keySet) {
            if (s.startsWith(BASEDATABASE)) {
                if (s.contains("slave")) {
                    slaveDataSourceNames.add(s);
                }
                map.put(s, dataSourceMap.get(s));
            }
        }
        //具体分库分表策略
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        // 不分库分表情况下的数据源制定--默认数据库
        shardingRuleConfig.setDefaultDataSourceName(BASEDATABASE + "-master");
        // 默认的分表规则
        shardingRuleConfig.setDefaultTableShardingStrategyConfig(new NoneShardingStrategyConfiguration());
        // database
//        shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("create_date", "data$->{create_date % 4}"));
        // 指定表的主键生成策略为SNOWFLAKE
        shardingRuleConfig.setDefaultKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "id"));

        Collection<MasterSlaveRuleConfiguration> masterSlaveRuleConfigs = new LinkedList<>();
        MasterSlaveRuleConfiguration masterSlaveRuleConfiguration
                = new MasterSlaveRuleConfiguration(BASEDATABASE, BASEDATABASE + "-master",
                // 从库集合
                slaveDataSourceNames,
                // 轮训策略
                new LoadBalanceStrategyConfiguration("round_robin"));

        masterSlaveRuleConfigs.add(masterSlaveRuleConfiguration);

        shardingRuleConfig.setMasterSlaveRuleConfigs(masterSlaveRuleConfigs);

        // 设置分表
        shardingRuleConfig.setTableRuleConfigs(BaseTableRuleConfig.getTableRuleConfigurations());

        return ShardingDataSourceFactory.createDataSource(map, shardingRuleConfig, getProperties());
    }
}